package com.ych.config;

import com.ych.auth.AuthRealm;
import com.ych.auth.CredentialMatcher;
import com.ych.init.filter.OAuth2Filter;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2020/12/5
 * Time: 15:02
 * Description:
 */
@Configuration
public class ShiroConfig {
    //定义shiroFilter，传入securityManager
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        //oauth过滤 加入自定义的过滤器
        Map<String, Filter> filters = new HashMap<>();
        filters.put("oauth2", new OAuth2Filter());
        shiroFilter.setFilters(filters);
        //key：代表访问的请求  value：代表使用的拦截器   DefaultFilter.authc
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
        /**
         * 开放swagger相关调用
         */
        filterMap.put("/swagger-resources/**", "anon");//输出
        filterMap.put("/v2/api-docs", "anon");//文档
        filterMap.put("/v2/api-docs-ext", "anon");//文档
        filterMap.put("/doc.html", "anon");
        filterMap.put("/webjars/**", "anon");
        /**
         * 开放系统内部相关调用
         */
        filterMap.put("/druid/**", "anon");//开放sql监控
        filterMap.put("/favicon.ico", "anon");
        filterMap.put("/api/unAuth/**", "anon");
        filterMap.put("/cms/unAuth/**", "anon");
        filterMap.put("/file/**", "anon");
        /**
         * 开启过滤拦截
         */
//        filterMap.put("/**", "authc");
        filterMap.put("/**", "oauth2");//使用自定义过滤器
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

    //定义securityManager，传入realm
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }

    //定义realm，传入密码比较器
    @Bean("authRealm")
    public AuthRealm authRealm(@Qualifier("credentialMatcher") CredentialMatcher credentialMatcher) {
        AuthRealm authRealm = new AuthRealm();
        authRealm.setCredentialsMatcher(credentialMatcher);
        return authRealm;
    }

    //定义密码比较器
    @Bean("credentialMatcher")
    public CredentialMatcher credentialMatcher() {
        return new CredentialMatcher();
    }

    /**************以下是shiro与spring的关联配置******************/
    /**
     * 开启aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     *
     * @param securityManager
     * @return
     */
    @Bean("authorizationAttributeSourceAdvisor")
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    @Bean("defaultAdvisorAutoProxyCreator")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
}
